package com.dream21th.dream21thredis.handler.filter;

import java.io.IOException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.dream21th.dream21thredis.handler.MyRequestWrapper;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class HttpFilter implements Filter {

	private static String[] safeless = {  //需要拦截的JS字符关键字 
            "<",
            ">",
            "%3c",  // < 编码
            "%3e",  // > 编码
            "set-cookie",
            "src=\"javascript:",
            "\'", //单引号
            "27%", //单引号 编码
            //	"\"", //双引号
            "22%", //双引号 编码
            "eval",
            " ",//空格
            "%20"
    };
	
	@Override
	public void destroy() {
		log.info("do destory");
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		log.info("do filter");
		HttpServletRequest httpServletRequest = (HttpServletRequest) request;
		MyRequestWrapper myRequestWrapper = null;

		Map<String, Object> params = new HashMap<>();
		// 封装请求参数
		switch (((HttpServletRequest) request).getMethod()) {
		case "POST":
			try {
				myRequestWrapper = new MyRequestWrapper((HttpServletRequest) request);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			JSONObject jsonObject = JSONObject.parseObject(myRequestWrapper.getBody());
			if(Objects.nonNull(jsonObject)){
				for (String key : jsonObject.keySet()) {
					params.put(key, jsonObject.get(key));
				}
			}
			break;
		case "GET":
			Enumeration<String> pNames = request.getParameterNames();
			while (pNames.hasMoreElements()) {
				String pName = pNames.nextElement();
				params.put(pName, request.getParameter(pName));
			}
			break;
		default:
			break;
		}
		if(!checkParams(params)){
			request.getRequestDispatcher("/redisLock/error").forward(
                    request, response);
		}else{
			chain.doFilter(myRequestWrapper == null ? request : myRequestWrapper, response);
		}
	}

	@Override
	public void init(FilterConfig arg0) throws ServletException {
		log.info("do init");
	}

	
	private boolean checkParams(Map<String,Object> params){
		for(Map.Entry<String, Object> map:params.entrySet()){
			String key=map.getKey();
			Object value=map.getValue();
			if(Objects.nonNull(value)){
				if(value instanceof String){
					for(String unsafe:safeless){
						if(((String)value).contains(unsafe)){
							log.info("参数：【{}】中，包含非法字符：【{}】",key,unsafe);
							return false;
						}
					}
				}else if(value instanceof JSONObject){
					Map<String,Object> map1=JSON.parseObject(JSON.toJSONString(value), Map.class);
					if(!checkParams(map1)){
						return false;
					};
				}else if(value instanceof JSONArray){
					for(int i=0;i<((JSONArray)value).size();i++){
						Map<String,Object> map2=JSON.parseObject(JSON.toJSONString(((JSONArray)value).get(i)), Map.class);
						if(!checkParams(map2)){
							return false;
						};
					}
				}
			}
		}
		
		return true;
	}
}
